#include <vector>
#include <stdio.h>
#include <math.h>
#include "player.h"
#include "databank.h"
#include "sprite.h"

using namespace std;

class Weapon;
class Player;

void Player::input() {

    if (key[KEY_LEFT]) {
        flagLeft = true;
    }

    if (key[KEY_RIGHT]) {
        flagRight = true;
    }

    if (key[KEY_SPACE]) {
        flagFire = true;
    }

    if(key[KEY_UP]) flagUp = true;
    if(key[KEY_DOWN]) flagDown = true;

    if(key[KEY_N]) flagNext = true;
}

TurnStatus Player::process(double delta) {

    if (flagLeft) {
        direction -= delta * FPS * 0.6;
        direction_update = true;
        flagLeft = false;
    }

    if (flagRight) {
        direction += delta * FPS * 0.6;
        direction_update = true;
        flagRight = false;
    }

    if((flagNext && !key[KEY_N]) || cweapon == NULL) {
        cweapon = intf.nextWeapon(weapons);
        flagNext = 0;
    }

    if (flagUp) {
        flagUp = false;

        if (power <= 9000.0) {
            power += delta * 4000.0;
        }

        // Power is never OVER NIIINE THOUSAND!!!11
        if (power > 9000.0) power = 9000.0;
    } else if (flagDown) {
        flagDown = false;

        if (power <= 9000.0) {
            power -= delta * 4000.0;
        }
        if (power < 0.0) power = 0.0;
    }

    if (flagFire && !key[KEY_SPACE]) {
        double vel[2];
        double dirr = 2*PIE*direction/256;

        // Realizing that 9000 power is a little bit much, we scale it down
        vel[0] = -(power/30.0)*cos(dirr);
        vel[1] = -(power/30.0)*sin(dirr);
        double pos[2];
        pos[0] = position[0] - cos(dirr)*18.0;
        pos[1] = position[1] - sin(dirr)*18.0;
        cweapon->fire(this, myDatabank,pos,vel);
        flagFire = false;

        return TURN_FINISHED;
    }

    updateBitmap();

    return TURN_UNFINISHED;
}


// Section
void Player::setup()
{
    int w,h,avg;
    w = myDatabank->sprites->player->w;
    h = myDatabank->sprites->player->h;
    avg = (w+h)/2;

    // Copy bitmap
    plbmp = create_bitmap(myDatabank->sprites->player->w,
            myDatabank->sprites->player->h);
    clear_to_color(plbmp, makecol(255,0,255));
    draw_sprite(plbmp, myDatabank->sprites->player, 0,0);

    // Change all pixels of "magic blue" to the player color
    for(int y=0;y<plbmp->h;y++) {
        for(int x=0;x<plbmp->w;x++) {
            if(getpixel(plbmp,x,y) == makecol(11,90,135)) {
                putpixel(plbmp, x,y, color);
            }
        }
    }

    rotated = create_bitmap(avg*2,avg*2); // Simple definition
    clear_to_color(rotated, makecol(255,0,255));

    direction_update = true;
    updateBitmap();
}

void Player::updateBitmap()
{
    if(direction_update) {
        // Direction fix injection
        while(direction < 0.0) direction += 256.0;
        direction = fmod(direction,256.0);

        direction_update = false;

        clear_to_color(rotated, makecol(255,0,255));
        pivot_sprite(rotated, plbmp, rotated->w/2, rotated->h/2,
                plbmp->w/2, plbmp->h/2, ftofix(direction));
    }
}

bool Player::testCollision(double *pos)
{
    int x,y;
    x = int(pos[0])-int(position[0])+rotated->w/2;
    y = int(pos[1])-int(position[1])+rotated->h/2;

    // Test out-of-bounds
    if(x<0 || x >= rotated->w ||
            y<0 || y >= rotated->h)
        return false;
    if(_getpixel32(rotated,x,y) == magicPink) {
        return false;
    }

    return true;
}

// Explode into glorious particles
void Player::die(DataBank *d)
{
    // Loop through the bitmap and make particles
    for(int y = 0; y < rotated->h; y++) {
        for(int x = 0; x < rotated->w; x++) {
            // Make particle
            int col = getpixel(rotated, x,y);
            if(col != magicPink) {
                double pos[2] = {x+int(position[0])-rotated->w/2,
                    y+int(position[1])-rotated->h/2};
                double vel[2] = {-5.0+frand()*10.0,-5.0+frand()*10.0};
                d->makeParticle(pos,vel, col);
            }
        }
    }
}

void Player::testDead(DataBank *d)
{
    if(hp <= 0 && !flagDead) {
        flagDead = true;
        die(d);
    }
}
